﻿using System.Diagnostics;

using IotClientService;
using IotContract.Interfaces;
using IotContract.Enums;
using IotContract.Interfaces.Process;
using XT.Common.Interfaces;
using XT.Common.Services;
using XT.Common.WinServices;
using XT.Common.Config;
using XT.Common.Extensions;
using XT.Common.Models.SignalR;
using XT.Common.Enums;
using IotContract.Configs;

namespace IotServer.Services;

public class ServerWinService : TimerService
{
    private ILogService _logService;
    private ISignalRService _signalRService;
    private IClientMainManager _clientMainManager;
    private IServiceProvider _serviceProvider;
    private IServerMainManager _serverMainManager;
    private IMqttServerService _mqttService;
    private string _programName = string.Empty;
    private AddressConfig _addressConfig;



    private IConnectDataService _connectDataService;

    // 程序id
    private long _programId = 0;
    // 轮询次数
    private int _times = 0;
    // 程序状态
    private ProgramStatusType _status = ProgramStatusType.Offline;
   
    /// <summary>
    /// 错误
    /// </summary>
    private string _error=string.Empty;
    private string _remark = string.Empty;
    
    private CancellationTokenSource? _cancellationTokenSource;
    public ServerWinService(ILogService logService, ISignalRService signalRService, IApiConfig apiConfig,IProcessApiHandle processApi,IConnectDataService connectDataService,IClientMainManager manager,IServiceProvider provider, IServerMainManager serverMainManager, IMqttServerService mqttService)
    {
        _logService = logService;
        _signalRService = signalRService;
        _serviceProvider = provider;
        _connectDataService = connectDataService;
        _clientMainManager = manager;
        _serverMainManager = serverMainManager;
        _mqttService = mqttService;
          _addressConfig = AppSettings.GetObjData<AddressConfig>("AddressConfig");
        // 远程WebApi地址
        apiConfig.RemoteApiUrl = _addressConfig.AdminUrl;
        processApi.RemoteApiUrl = _addressConfig.ApiUrl;
        // 程序名称
        _programName = AppSettings.GetValue("ProgramName");
        
    }


    public async override Task Start()
    {
        StartBase();
        _cancellationTokenSource = new CancellationTokenSource();
      
        _error = string.Empty;

        // 开始进行数据添加
        var programResult = await _connectDataService.AddProgram(new IotContract.Models.Clients.ClientConnectCommand
        {
            IPAddress = WindowProcessService.GetLocalIp(),
            ProgramType = (int)IotProgramType.IotServer,
            RunPath = Process.GetCurrentProcess().MainModule.FileName
        });
        _logService.Log($"Initial Success,Ecs Api Address Is {_connectDataService.AddressConfig.ApiUrl}");
        if (programResult.Item2.IsNotNullOrEmpty()) { _logService.LogError($"Error Run {programResult.Item2}");return; }

        _programId = programResult.Item1.Id;
        _programName = programResult.Item1.Name;

        var result = await ConnectSignalR();

        if (!result)
        {
            _error = "SignalR connect error";
            _logService.LogError($"Please Check RemoteAddress In appsettins.json，Not Connect Ecs Api");
        }

        
      


        if (_programId > 0)
        {
           
            // 启动关联设备
            await RunEquips(_programId);
            
            // 启动数据推送
            Timers.Start("PushAndWrite", 500, async () =>
            {
                await _clientMainManager.PushAndWirte();
            });
            
           // 启动处理程序
            await ProcessRun();

            // 上报状态，如果报错，启动失败
             await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
            {
                ProgramId = _programId,
                Name = _programName,
                Status = IotContract.Enums.ProgramStatusType.Online,
                StatusDes = _error,
                Remark=_remark
            });


            _status = ProgramStatusType.Online;

          


        }


        // 读取控制命令
        Timers.Start("ReportStatus", 60000, async () =>
        {
 
                if (_programId > 0)
                {
                    await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
                    {
                        ProgramId = _programId,
                        Name = _programName,
                        Status = _status,
                        StatusDes = _error,
                        Remark= _remark
                        
                    });

                }


        });

        // 服务端初始化相关服务
        await _mqttService.Initial();
        
        await HandleControls();
      

    }
    /// <summary>
    /// 启动设备
    /// </summary>
    /// <returns></returns>
    private async Task<bool> RunEquips(long programId,long equipId = 0)
    {

        // 读取设备数据
        var msgData = await _connectDataService.GetEquips(new IotContract.Models.Clients.ClientRequestCommand
        {
            ProgramId = programId,
            EquipId = equipId

        });
        if (msgData.Item2.IsNotNullOrEmpty())
        {
            _error = $"Error Run Equips，{msgData.Item2}";
           _logService.LogError(_error);
            return false;
        }
        else
        {

            var equips = msgData.Item1;

            if (equips == null || equips.Count == 0)
            {
                _error = $"Get No Equips,Not Run";
                _logService.Log(_error);
                return false;

            }
            else
            {
                if (equipId == 0)
                {
                    await _clientMainManager.Stop(_programId);
                }

                await _clientMainManager.Run(equips);

                _error = $"Success Run Equips {equips.Count}";
                _logService.Log(_error);
                _status = ProgramStatusType.Running;

                return true;


            }
        }
    }
    /// <summary>
    /// 启动处理程序
    /// </summary>
    /// <returns></returns>
    private async Task ProcessRun()
    {
       var process= _serviceProvider.GetServices<IServerMainProcess>();
        if(process != null)
        {
           
            foreach(var p in process)
            {
               await p.Run();

               _remark = $"{p.ProcessName} Process Dll Run Success";
            }
           
               
            
        }
    }
  

    /// <summary>
    /// 轮询控制指令
    /// </summary>
    /// <returns></returns>
    private async Task HandleControls()
    {
        await foreach(var control in _clientMainManager.ReadControl(new IotContract.Models.Clients.ClientRequestCommand
        {
            ProgramId = _programId
        }, _cancellationTokenSource.Token))
        {
            if (control.ControlType == ProgramControlType.StopProcess)
            {

                await ProcessStop();
            }
            else if (control.ControlType == ProgramControlType.RunProcess)
            {
                await ProcessRun();
            }
            else if (control.ControlType == ProgramControlType.Run)
            {
                await RunEquips(control.ProgramId);
            }
            else if (control.ControlType == ProgramControlType.Connect)
            {
                await RunEquips(control.ProgramId, control.EquipId);
            }
            else if (control.ControlType == IotContract.Enums.ProgramControlType.Stop)
            {
                // 针对服务设备单独处理,清理所有数据
                await _serverMainManager.ClearEquips();
            }
        }
       
    }
    /// <summary>
    /// 停止处理程序
    /// </summary>
    /// <returns></returns>
    private async Task ProcessStop()
    {
        var process = _serviceProvider.GetServices<IServerMainProcess>();
        if (process != null)
        {
            foreach (var p in process)
            {
                await p.Stop();
            }
            _remark = "Process dll Stop";

            // 上报状态，如果报错，启动失败
            await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
            {
                ProgramId = _programId,
                Name = _programName,
                Status = IotContract.Enums.ProgramStatusType.Online,
                StatusDes = _error,
                Remark = _remark
            }) ;
        }
    }

    public async override Task Stop()
    {
        _cancellationTokenSource?.Cancel();


        _logService.Log("Server Stop");
        // 上报状态

        await _connectDataService.CommitStatus(new IotContract.Models.Clients.ClientStatusCommand
        {
            ProgramId = _programId,
            Name = _programName,
            Status = IotContract.Enums.ProgramStatusType.Offline,
            StatusDes = "Server Stop"

        });

        await ProcessStop();

        await _signalRService.StopServer();

        await _mqttService.StopMqtt();

        StopBase();
    }
    /// <summary>
    /// 连接SignalR
    /// </summary>
    /// <returns></returns>
    public async Task<bool> ConnectSignalR()
    {
        if (_programName.IsNullOrEmpty())
        {
            return false;
        }
      
        // 连接SignalR服务，推送消息和日志
        var result = await _signalRService.ConnectServer(_addressConfig.AdminUrl, new User
        {
            ID = Guid.NewGuid().ToString(),
            Name = _programName,
            Type = DeviceEnum.Service
        });
        



        return result;
    }

   
   
}
